<%= lines(autogen_notice(:go, pwd)) -%>

package google

import (
	"fmt"
	"testing"

	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest"
	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
	"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
)

<%# Since most resources define a "basic" config as their first example, we can reuse that config to create a resource to test IAM resources with. -%>
<% example = object.examples.reject(&:skip_test)
         .reject { |e| @api.version_obj_or_closest(version) < @api.version_obj_or_closest(e.min_version) }
         .first -%>
<% resource_name = product_ns + object.name -%>
<%
individual_url = object.iam_policy.self_link || object.self_link_url
-%>
<%
  tf_product = (@config.legacy_name || product_ns).underscore
  resource_ns = object.legacy_name || "google_#{tf_product}_#{object.name.underscore}"
  resource_ns_iam = resource_ns + '_iam'
-%>
<%
if object.iam_policy.import_format
	import_format = object.iam_policy.import_format.first
else
	import_format = individual_url
end
params = extract_identifiers(import_format.gsub('{{name}}', "{{#{object.name.underscore}}}"))
import_url = import_format.gsub(/({{)%?(\w+)(}})/, '%s').gsub(object.__product.base_url, '')
-%>
<% import_qualifiers = [] -%>
<% params.each_with_index do |param, i| -%>
	<% if param == 'project' -%>
		<% if i != params.size - 1 -%>
			<%# If the last parameter is project then we want to create a new project to use for the test, so don't default from the environment -%>
			<% if object.iam_policy.test_project_name.nil? -%>
				<% import_qualifiers.push('getTestProjectFromEnv()') -%>
			<% else -%>
				<% import_qualifiers.push('context["project_id"]') -%>
			<% end -%>
		<% end -%>
	<% elsif param == 'zone' -%>
		<% import_qualifiers.push('getTestZoneFromEnv()') -%>
	<% elsif param == 'region' || param == 'location' -%>
		<% if example.region_override.nil? -%>
				<% import_qualifiers.push('getTestRegionFromEnv()') -%>
			<% else -%>
				<% import_qualifiers.push("\"#{example.region_override}\"") -%>
			<% end -%>
	<% end -%>
<% end -%>
func TestAcc<%= resource_name -%>IamBindingGenerated(t *testing.T) {
	t.Parallel()

<%= lines(compile(pwd + '/templates/terraform/iam/iam_context.go.erb')) -%>

	vcrTest(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
<% unless object.min_version.name == "ga" -%>
		Providers:    testAccProvidersOiCS,
<% else -%>
		Providers:    testAccProviders,
<% end -%>
		Steps: []resource.TestStep{
			{
				Config: testAcc<%= resource_name -%>IamBinding_basicGenerated(context),
			},
<% if object.min_version.name == "ga" -%>
			{
				ResourceName:      "<%= resource_ns_iam -%>_binding.foo",
				ImportStateId:     fmt.Sprintf("<%= import_url -%> <%= object.iam_policy.allowed_iam_role -%>"<% unless import_qualifiers.empty? -%>, <% end -%><%= import_qualifiers.join(', ') -%>, <%= example.primary_resource_name -%>),
				ImportState:       true,
				ImportStateVerify: true,
			},
<% end -%>
			{
				// Test Iam Binding update
				Config: testAcc<%= resource_name -%>IamBinding_updateGenerated(context),
			},
<% if object.min_version.name == "ga" -%>
			{
				ResourceName:      "<%= resource_ns_iam -%>_binding.foo",
				ImportStateId:     fmt.Sprintf("<%= import_url -%> <%= object.iam_policy.allowed_iam_role -%>"<% unless import_qualifiers.empty? -%>, <% end -%><%= import_qualifiers.join(', ') -%>, <%= example.primary_resource_name -%>),
				ImportState:       true,
				ImportStateVerify: true,
			},
<% end -%>
		},
	})
}

func TestAcc<%= resource_name -%>IamMemberGenerated(t *testing.T) {
	t.Parallel()

<%= lines(compile(pwd + '/templates/terraform/iam/iam_context.go.erb')) -%>

	vcrTest(t, resource.TestCase{
		PreCheck:  func() { testAccPreCheck(t) },
<% unless object.min_version.name == "ga" -%>
		Providers: testAccProvidersOiCS,
<% else -%>
		Providers: testAccProviders,
<% end -%>
		Steps: []resource.TestStep{
			{
				// Test Iam Member creation (no update for member, no need to test)
				Config: testAcc<%= resource_name -%>IamMember_basicGenerated(context),
			},
<% if object.min_version.name == "ga" -%>
			{
				ResourceName:      "<%= resource_ns_iam -%>_member.foo",
				ImportStateId:     fmt.Sprintf("<%= import_url -%> <%= object.iam_policy.allowed_iam_role -%> user:admin@hashicorptest.com"<% unless import_qualifiers.empty? -%>, <% end -%><%= import_qualifiers.join(', ') -%>, <%= example.primary_resource_name -%>),
				ImportState:       true,
				ImportStateVerify: true,
			},
<% end -%>
		},
	})
}

func TestAcc<%= resource_name -%>IamPolicyGenerated(t *testing.T) {
	t.Parallel()

<% unless object.iam_policy.admin_iam_role.nil? -%>
	// This may skip test, so do it first
	sa := getTestServiceAccountFromEnv(t)
<% end -%>
<%= lines(compile(pwd + '/templates/terraform/iam/iam_context.go.erb')) -%>
<% unless object.iam_policy.admin_iam_role.nil? -%>
	context["service_account"] = sa
<% end -%>

	vcrTest(t, resource.TestCase{
		PreCheck:  func() { testAccPreCheck(t) },
<% unless object.min_version.name == "ga" -%>
		Providers: testAccProvidersOiCS,
<% else -%>
		Providers: testAccProviders,
<% end -%>
		Steps: []resource.TestStep{
			{
				Config: testAcc<%= resource_name -%>IamPolicy_basicGenerated(context),
			},
<% if object.min_version.name == "ga" -%>
			{
				ResourceName:      "<%= resource_ns_iam -%>_policy.foo",
				ImportStateId:     fmt.Sprintf("<%= import_url -%>"<% unless import_qualifiers.empty? -%>, <% end -%><%= import_qualifiers.join(', ') -%>, <%= example.primary_resource_name -%>),
				ImportState:       true,
				ImportStateVerify: true,
			},
<% end -%>
			{
				Config: testAcc<%= resource_name -%>IamPolicy_emptyBinding(context),
			},
<% if object.min_version.name == "ga" -%>
			{
				ResourceName:      "<%= resource_ns_iam -%>_policy.foo",
				ImportStateId:     fmt.Sprintf("<%= import_url -%>"<% unless import_qualifiers.empty? -%>, <% end -%><%= import_qualifiers.join(', ') -%>, <%= example.primary_resource_name -%>),
				ImportState:       true,
				ImportStateVerify: true,
			},
<% end -%>
		},
	})
}

<% unless version == 'ga' || object.iam_policy.iam_conditions_request_type.nil? -%>
func TestAcc<%= resource_name -%>IamBindingGenerated_withCondition(t *testing.T) {
	t.Parallel()

<%= lines(compile(pwd + '/templates/terraform/iam/iam_context.go.erb')) -%>

	vcrTest(t, resource.TestCase{
		PreCheck:  func() { testAccPreCheck(t) },
<% unless object.min_version.name == "ga" -%>
		Providers: testAccProvidersOiCS,
<% else -%>
		Providers: testAccProviders,
<% end -%>
		Steps: []resource.TestStep{
			{
				Config: testAcc<%= resource_name -%>IamBinding_withConditionGenerated(context),
			},
<% if object.min_version.name == "ga" -%>
			{
				ResourceName:      "<%= resource_ns_iam -%>_binding.foo",
				ImportStateId:     fmt.Sprintf("<%= import_url -%> <%= object.iam_policy.allowed_iam_role -%> %s"<% unless import_qualifiers.empty? -%>, <% end -%><%= import_qualifiers.join(', ') -%>, <%= example.primary_resource_name -%>, context["condition_title"]),
				ImportState:       true,
				ImportStateVerify: true,
			},
<% end -%>
		},
	})
}

func TestAcc<%= resource_name -%>IamBindingGenerated_withAndWithoutCondition(t *testing.T) {
	// Multiple fine-grained resources
	skipIfVcr(t)
	t.Parallel()

<%= lines(compile(pwd + '/templates/terraform/iam/iam_context.go.erb')) -%>

	vcrTest(t, resource.TestCase{
		PreCheck:  func() { testAccPreCheck(t) },
<% unless object.min_version.name == "ga" -%>
		Providers: testAccProvidersOiCS,
<% else -%>
		Providers: testAccProviders,
<% end -%>
		Steps: []resource.TestStep{
			{
				Config: testAcc<%= resource_name -%>IamBinding_withAndWithoutConditionGenerated(context),
			},
<% if object.min_version.name == "ga" -%>
			{
				ResourceName:      "<%= resource_ns_iam -%>_binding.foo",
				ImportStateId:     fmt.Sprintf("<%= import_url -%> <%= object.iam_policy.allowed_iam_role -%>"<% unless import_qualifiers.empty? -%>, <% end -%><%= import_qualifiers.join(', ') -%>, <%= example.primary_resource_name -%>),
				ImportState:       true,
				ImportStateVerify: true,
			},
<% end -%>
<% if object.min_version.name == "ga" -%>
			{
				ResourceName:      "<%= resource_ns_iam -%>_binding.foo2",
				ImportStateId:     fmt.Sprintf("<%= import_url -%> <%= object.iam_policy.allowed_iam_role -%> %s"<% unless import_qualifiers.empty? -%>, <% end -%><%= import_qualifiers.join(', ') -%>, <%= example.primary_resource_name -%>, context["condition_title"]),
				ImportState:       true,
				ImportStateVerify: true,
			},
<% end -%>
		},
	})
}

func TestAcc<%= resource_name -%>IamMemberGenerated_withCondition(t *testing.T) {
	t.Parallel()

<%= lines(compile(pwd + '/templates/terraform/iam/iam_context.go.erb')) -%>

	vcrTest(t, resource.TestCase{
		PreCheck:  func() { testAccPreCheck(t) },
<% unless object.min_version.name == "ga" -%>
		Providers: testAccProvidersOiCS,
<% else -%>
		Providers: testAccProviders,
<% end -%>
		Steps: []resource.TestStep{
			{
				Config: testAcc<%= resource_name -%>IamMember_withConditionGenerated(context),
			},
<% if object.min_version.name == "ga" -%>
			{
				ResourceName:      "<%= resource_ns_iam -%>_member.foo",
				ImportStateId:     fmt.Sprintf("<%= import_url -%> <%= object.iam_policy.allowed_iam_role -%> user:admin@hashicorptest.com %s"<% unless import_qualifiers.empty? -%>, <% end -%><%= import_qualifiers.join(', ') -%>, <%= example.primary_resource_name -%>, context["condition_title"]),
				ImportState:       true,
				ImportStateVerify: true,
			},
<% end -%>
		},
	})
}

func TestAcc<%= resource_name -%>IamMemberGenerated_withAndWithoutCondition(t *testing.T) {
	// Multiple fine-grained resources
	skipIfVcr(t)
	t.Parallel()

<%= lines(compile(pwd + '/templates/terraform/iam/iam_context.go.erb')) -%>

	vcrTest(t, resource.TestCase{
		PreCheck:  func() { testAccPreCheck(t) },
<% unless object.min_version.name == "ga" -%>
		Providers: testAccProvidersOiCS,
<% else -%>
		Providers: testAccProviders,
<% end -%>
		Steps: []resource.TestStep{
			{
				Config: testAcc<%= resource_name -%>IamMember_withAndWithoutConditionGenerated(context),
			},
<% if object.min_version.name == "ga" -%>
			{
				ResourceName:      "<%= resource_ns_iam -%>_member.foo",
				ImportStateId:     fmt.Sprintf("<%= import_url -%> <%= object.iam_policy.allowed_iam_role -%> user:admin@hashicorptest.com"<% unless import_qualifiers.empty? -%>, <% end -%><%= import_qualifiers.join(', ') -%>, <%= example.primary_resource_name -%>),
				ImportState:       true,
				ImportStateVerify: true,
			},
<% end -%>
<% if object.min_version.name == "ga" -%>
			{
				ResourceName:      "<%= resource_ns_iam -%>_member.foo2",
				ImportStateId:     fmt.Sprintf("<%= import_url -%> <%= object.iam_policy.allowed_iam_role -%> user:admin@hashicorptest.com %s"<% unless import_qualifiers.empty? -%>, <% end -%><%= import_qualifiers.join(', ') -%>, <%= example.primary_resource_name -%>, context["condition_title"]),
				ImportState:       true,
				ImportStateVerify: true,
			},
<% end -%>
		},
	})
}

func TestAcc<%= resource_name -%>IamPolicyGenerated_withCondition(t *testing.T) {
	t.Parallel()

<% unless object.iam_policy.admin_iam_role.nil? -%>
	// This may skip test, so do it first
	sa := getTestServiceAccountFromEnv(t)
<% end -%>
<%= lines(compile(pwd + '/templates/terraform/iam/iam_context.go.erb')) -%>
<% unless object.iam_policy.admin_iam_role.nil? -%>
	context["service_account"] = sa
<% end -%>

	vcrTest(t, resource.TestCase{
		PreCheck:  func() { testAccPreCheck(t) },
<% unless object.min_version.name == "ga" -%>
		Providers: testAccProvidersOiCS,
<% else -%>
		Providers: testAccProviders,
<% end -%>
		Steps: []resource.TestStep{
			{
				Config: testAcc<%= resource_name -%>IamPolicy_withConditionGenerated(context),
			},
<% if object.min_version.name == "ga" -%>
			{
				ResourceName:      "<%= resource_ns_iam -%>_policy.foo",
				ImportStateId:     fmt.Sprintf("<%= import_url -%>"<% unless import_qualifiers.empty? -%>, <% end -%><%= import_qualifiers.join(', ') -%>, <%= example.primary_resource_name -%>),
				ImportState:       true,
				ImportStateVerify: true,
			},
<% end -%>
		},
	})
}
<% end -%>

func testAcc<%= resource_name -%>IamMember_basicGenerated(context map[string]interface{}) string {
	return Nprintf(`
<%= example.config_test_body(pwd) -%>

resource "<%= resource_ns_iam -%>_member" "foo" {
<% unless object.min_version.name == "ga" -%>
  provider = google-beta
<% end -%>
<%= lines(compile(pwd + '/' + object.iam_policy.example_config_body)) -%>
  role = "%{role}"
  member = "user:admin@hashicorptest.com"
}
`, context)
}

func testAcc<%= resource_name -%>IamPolicy_basicGenerated(context map[string]interface{}) string {
	return Nprintf(`
<%= example.config_test_body(pwd) -%>

data "google_iam_policy" "foo" {
<% unless object.min_version.name == "ga" -%>
  provider = google-beta
<% end -%>
  binding {
    role = "%{role}"
    members = ["user:admin@hashicorptest.com"]
  }
<% unless object.iam_policy.admin_iam_role.nil? -%>
  binding {
    role = "%{admin_role}"
    members = ["serviceAccount:%{service_account}"]
  }
<% end -%>
}

resource "<%= resource_ns_iam -%>_policy" "foo" {
<% unless object.min_version.name == "ga" -%>
  provider = google-beta
<% end -%>
<%= lines(compile(pwd + '/' + object.iam_policy.example_config_body)) -%>
  policy_data = data.google_iam_policy.foo.policy_data
}
`, context)
}

func testAcc<%= resource_name -%>IamPolicy_emptyBinding(context map[string]interface{}) string {
	return Nprintf(`
<%= example.config_test_body(pwd) -%>

data "google_iam_policy" "foo" {
<% unless object.min_version.name == "ga" -%>
  provider = google-beta
<% end -%>
}

resource "<%= resource_ns_iam -%>_policy" "foo" {
<% unless object.min_version.name == "ga" -%>
  provider = google-beta
<% end -%>
<%= lines(compile(pwd + '/' + object.iam_policy.example_config_body)) -%>
  policy_data = data.google_iam_policy.foo.policy_data
}
`, context)
}

func testAcc<%= resource_name -%>IamBinding_basicGenerated(context map[string]interface{}) string {
	return Nprintf(`
<%= example.config_test_body(pwd) -%>

resource "<%= resource_ns_iam -%>_binding" "foo" {
<% unless object.min_version.name == "ga" -%>
  provider = google-beta
<% end -%>
<%= lines(compile(pwd + '/' + object.iam_policy.example_config_body)) -%>
  role = "%{role}"
  members = ["user:admin@hashicorptest.com"]
}
`, context)
}

func testAcc<%= resource_name -%>IamBinding_updateGenerated(context map[string]interface{}) string {
	return Nprintf(`
<%= example.config_test_body(pwd) -%>

resource "<%= resource_ns_iam -%>_binding" "foo" {
<% unless object.min_version.name == "ga" -%>
  provider = google-beta
<% end -%>
<%= lines(compile(pwd + '/' + object.iam_policy.example_config_body)) -%>
  role = "%{role}"
  members = ["user:admin@hashicorptest.com", "user:paddy@hashicorp.com"]
}
`, context)
}

<% unless version == 'ga' || object.iam_policy.iam_conditions_request_type.nil? -%>
func testAcc<%= resource_name -%>IamBinding_withConditionGenerated(context map[string]interface{}) string {
	return Nprintf(`
<%= example.config_test_body(pwd) -%>

resource "<%= resource_ns_iam -%>_binding" "foo" {
<% unless object.min_version.name == "ga" -%>
  provider = google-beta
<% end -%>
<%= lines(compile(pwd + '/' + object.iam_policy.example_config_body)) -%>
  role = "%{role}"
  members = ["user:admin@hashicorptest.com"]
  condition {
    title       = "%{condition_title}"
    description = "Expiring at midnight of 2019-12-31"
    expression  = "%{condition_expr}"
  }
}
`, context)
}

func testAcc<%= resource_name -%>IamBinding_withAndWithoutConditionGenerated(context map[string]interface{}) string {
	return Nprintf(`
<%= example.config_test_body(pwd) -%>

resource "<%= resource_ns_iam -%>_binding" "foo" {
<% unless object.min_version.name == "ga" -%>
  provider = google-beta
<% end -%>
<%= lines(compile(pwd + '/' + object.iam_policy.example_config_body)) -%>
  role = "%{role}"
  members = ["user:admin@hashicorptest.com"]
}

resource "<%= resource_ns_iam -%>_binding" "foo2" {
<% unless object.min_version.name == "ga" -%>
  provider = google-beta
<% end -%>
<%= lines(compile(pwd + '/' + object.iam_policy.example_config_body)) -%>
  role = "%{role}"
  members = ["user:admin@hashicorptest.com"]
  condition {
    title       = "%{condition_title}"
    description = "Expiring at midnight of 2019-12-31"
    expression  = "%{condition_expr}"
  }
}
`, context)
}

func testAcc<%= resource_name -%>IamMember_withConditionGenerated(context map[string]interface{}) string {
	return Nprintf(`
<%= example.config_test_body(pwd) -%>

resource "<%= resource_ns_iam -%>_member" "foo" {
<% unless object.min_version.name == "ga" -%>
  provider = google-beta
<% end -%>
<%= lines(compile(pwd + '/' + object.iam_policy.example_config_body)) -%>
  role = "%{role}"
  member = "user:admin@hashicorptest.com"
  condition {
    title       = "%{condition_title}"
    description = "Expiring at midnight of 2019-12-31"
    expression  = "%{condition_expr}"
  }
}
`, context)
}

func testAcc<%= resource_name -%>IamMember_withAndWithoutConditionGenerated(context map[string]interface{}) string {
	return Nprintf(`
<%= example.config_test_body(pwd) -%>

resource "<%= resource_ns_iam -%>_member" "foo" {
<% unless object.min_version.name == "ga" -%>
  provider = google-beta
<% end -%>
<%= lines(compile(pwd + '/' + object.iam_policy.example_config_body)) -%>
  role = "%{role}"
  member = "user:admin@hashicorptest.com"
}

resource "<%= resource_ns_iam -%>_member" "foo2" {
<% unless object.min_version.name == "ga" -%>
  provider = google-beta
<% end -%>
<%= lines(compile(pwd + '/' + object.iam_policy.example_config_body)) -%>
  role = "%{role}"
  member = "user:admin@hashicorptest.com"
  condition {
    title       = "%{condition_title}"
    description = "Expiring at midnight of 2019-12-31"
    expression  = "%{condition_expr}"
  }
}
`, context)
}

func testAcc<%= resource_name -%>IamPolicy_withConditionGenerated(context map[string]interface{}) string {
	return Nprintf(`
<%= example.config_test_body(pwd) -%>

data "google_iam_policy" "foo" {
<% unless object.min_version.name == "ga" -%>
  provider = google-beta
<% end -%>
  binding {
    role = "%{role}"
    members = ["user:admin@hashicorptest.com"]
    condition {
      title       = "%{condition_title}"
      description = "Expiring at midnight of 2019-12-31"
      expression  = "%{condition_expr}"
    }
  }
<% unless object.iam_policy.admin_iam_role.nil? -%>
  binding {
    role = "%{admin_role}"
    members = ["serviceAccount:%{service_account}"]
  }
<% end -%>
}

resource "<%= resource_ns_iam -%>_policy" "foo" {
<% unless object.min_version.name == "ga" -%>
  provider = google-beta
<% end -%>
<%= lines(compile(pwd + '/' + object.iam_policy.example_config_body)) -%>
  policy_data = data.google_iam_policy.foo.policy_data
}
`, context)
}
<% end -%>
